Separate core algo into a more generic version #12
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I would have opened an issue first but some ideas and benefits are easier to demonstrate as a PR and working example, so here goes…
This PR primarily separates the diff algorithm from supporting types
ListDiffAction<,>
,ListDiffActionType
andListDiff<,>
and renders it even more generic so that it can stand and be used on its own; this leads to many benefits.First and foremost, the core function becomes very generic:
The 3 functions
updateResult
,addResult
andremoveResult
project the result elements such that the function can return a simple list (List<>
) of those results. The shape ofR
is now up to the caller based on relevant inputs.The constructor of
ListDiff<,>
has been updated to use it as follows:The are several other overloads added for convenience. For example, when source and destination elements are the same some type T then you get a simpler signature:
This uses the default comparer (
EqualityComparer<T>.Default
) so a function to determine a match isn't needed. This also solves the boxing/performance problem highlighted in issue #8.Since we have tuples, we can go one step further for simpler scenarios with the following signature:
That is, given 3 tags to represent an update, add or remove node, the function will return a list of triplets where the source and destinations elements are annotated with the appropriate tag.
In its current design, the stand-alone
Diff
method is part of a class calledDiffModule
. This permits using the method directly via a static import (using static ListDiff.DiffModule
).I have also placed
DiffModule
in its own file and made the definition partial and private by default. Then inListDiff.cs
, the partial definition has thepublic
modifier to make it public. The idea behind this seemingly bizarre approach is that it enables someone to just takeDiff.cs
and run with it in their project without inheriting any dependencies or types of the project.DiffModule
will automatically become a private artifact of the user's project. However, when included together withListDiff.cs
as part of this project, it is exposed publicly.If you like what you see here, I am happy to put polishing touches like doc comments and argument validation.
Looking forward to your review and thoughts.